﻿/*
 * Реализация базового класса Актора. Служит в первую очередь для сокращения дублирования кода
 * при реализации реальных акторов, именно поэтому вынесен в библиотеку(ctem.kernel.lib)
 * В будущем может быть заменен на использование макросов, однако для реализации акторов на С#
 * всё равно остаётся полезен.
 * */

using System;
using System.Collections.Generic;
using System.Text;

using ctem.kernel;
using ctem.helpers;

namespace ctem.kernel.lib
{
    public class Actor : IActor
    {
        public Actor() { name = "NO NAME ASSIGNED - IT IS ERROR"; }

        public Actor(string name)
        { this.name = name; }

        protected Dictionary<string, IInPort> inports = new Dictionary<string, IInPort>();
        protected Dictionary<string, IOutPort> outports = new Dictionary<string, IOutPort>();
        protected Dictionary<string, IParam> parametrs = new Dictionary<string, IParam>();

        protected readonly string name;
        public string GetName() { return name; }

        public List<IPort> GetPorts()
        {
            List<IPort> iports=new List<IPort>();
            foreach (IInPort inport in inports.Values)
                iports.Add((IPort)inport);
            foreach (IOutPort outport in outports.Values)
                iports.Add((IPort)outport);
            return iports;
        }

        public IPort GetPortByName(string name)
        {
            
            IPort port = GetInPortByName(name);
            if (port == null)
                port = GetOutPortByName(name);
            return port;
        }

        public List<IInPort> GetInPorts() { return Converters.DictionaryToList<IInPort>(inports); }
        public IInPort GetInPortByName(string name)
        {
            IInPort inport;
            if (inports.TryGetValue(name, out inport))
                return inport;
            else
                return null;
        }

        public List<IOutPort> GetOutPorts() { return Converters.DictionaryToList<IOutPort>(outports); }
        public IOutPort GetOutPortByName(string name)
        {
            IOutPort outport;
            if (outports.TryGetValue(name, out outport))
                return outport;
            else
                return null;
        }

        public List<IParam> GetParams() { return Converters.DictionaryToList<IParam>(parametrs); }
        public IParam GetParamByName(string name)
        {
            IParam param;
            if (parametrs.TryGetValue(name, out param))
                return param;
            else
                return null;
        }

        protected void RegisterInport(IInPort inport)
        {
            inports.Add(inport.GetName(), inport);
        }

        protected void RegisterOutport(IOutPort outport)
        {
            outports.Add(outport.GetName(), outport);
        }

        protected void RegisterParam(IParam param)
        {
            parametrs.Add(param.GetName(), param);
        }

        public virtual void Dispose()
        {
            foreach (IInPort inport in inports.Values)
            {
                inport.Dispose();
            }
            inports.Clear();

            foreach (IOutPort outport in outports.Values)
            {
                outport.Dispose();
            }
            outports.Clear();

            foreach (IParam param in parametrs.Values)
            {
                param.Dispose();
            }
            parametrs.Clear();
        }

        public virtual void Fire(double step) { }
        public virtual void TemporaryStop() { }

        public virtual void ReInitialize() 
        {
            foreach (IInPort inport in inports.Values)
                inport.ReInitialize();
        }

        public virtual void OnStopModelling()
        {
            //Nul
        }

        public virtual void OnOfflineModeSet(long offlineDuration)
        {
            //Nul
        }

        public virtual void OnOnlineModeSet()
        {
            //Nul
        }

        public virtual void GetWDenom(ref double[] denom)
        {
            
        }

        protected double weight;
        public double Weight { get { return weight; } set { weight = value; } }

    }
	
}
